#include "StdAfx.h"

#include <MyControls/PropertyList.h>
#include <MyControls/PEditor.h>
#include <MyFC/Utility.h>

namespace My {

PropertyList::PropertyList(PEditor & e)
	: m_Editor(e)
{
	m_Editor.Add(this);
	m_ActiveRow = -1;
}

PropertyList::~PropertyList()
{
}

void PropertyList::OnRowsChanged()
{
	ToFront(&m_Editor.m_VSplitter);
	SetActiveRow(m_ActiveRow);
}

void PropertyList::SetValidActiveRow(int index)
{
	if (index < 0)
		index = 0;
	SetActiveRow(index);
}

void PropertyList::SetActiveRow(int index)
{
	if (index < -1)
		index = -1;
	if (index > int(GetRowCount()) - 1)
		index = int(GetRowCount()) - 1;
	if (index != m_ActiveRow) {
		if (m_ActiveRow != -1)
			GetRow(m_ActiveRow)->Invalidate();
		m_ActiveRow = index;
		if (m_ActiveRow != -1) {
			ClampInView(m_ActiveRow);
			GetRow(m_ActiveRow)->Invalidate();
		}
		m_Editor.m_Info.Invalidate();
	}
}

CRect PropertyList::Bounds() const
{
	CRect r = m_Editor.ClientRect();
	r.bottom -= m_Editor.GetInfoHeight();
	return r;
}

void PropertyList::HandlePaint(CDC * pDC, const CRect & r)
{
	My::SaveObjects save(pDC);

	COLORREF cS = GetSysColor(COLOR_BTNSHADOW);
	COLORREF cLF = My::MeanSysColor(COLOR_BTNFACE, COLOR_BTNHILIGHT);

	CBrush bFace(cLF);
	pDC->FillRect(&r, &bFace);

	CRect rClient =	ClientRect();

	CPen pShadow(PS_SOLID, 1, cS);
	pDC->SelectObject(&pShadow);

	int w = m_Editor.GetCaptionWidth();
	pDC->MoveTo(w, rClient.top);
	pDC->LineTo(w, rClient.bottom);
}

void PropertyList::HandleLeftDown(unsigned int flags, const CPoint & p)
{
	SetActiveRow(-1);
	ListControl::HandleLeftDown(flags, p);
}

bool PropertyList::HandleCursor(unsigned int flags, const CPoint & p)
{
	::SetCursor(::LoadCursor(NULL, IDC_ARROW));
	return true;
}

void PropertyList::HandleFocus()
{
	if (m_ActiveRow != -1)
		GetRow(m_ActiveRow)->Invalidate();
}

void PropertyList::HandleUnfocus()
{
	if (m_ActiveRow != -1)
		GetRow(m_ActiveRow)->Invalidate();
}

void PropertyList::HandleKeyDown(unsigned int key, unsigned int count, unsigned int flags)
{
	if (m_ActiveRow == -1)
		return;

	switch (key) {
	case VK_UP:
		SetValidActiveRow(m_ActiveRow - 1);
		break;
	case VK_DOWN:
		SetValidActiveRow(m_ActiveRow + 1);
		break;
	case VK_PRIOR: {
		int offset = GetRow(m_ActiveRow)->GetRowOffset() - GetOffset();
		int index = RowIndexAt(offset - Height());
		SetValidActiveRow(index);
		break;
	}
	case VK_NEXT: {
		int offset = GetRow(m_ActiveRow)->GetRowOffset() - GetOffset();
		int index = RowIndexAt(offset + Height());
		if (index == -1)
			index = GetRowCount() - 1;
		SetValidActiveRow(index);
		break;
	}
	case VK_HOME:
		SetValidActiveRow(0);
		break;
	case VK_END:
		SetValidActiveRow(GetRowCount() - 1);
		break;
	case VK_RETURN: {
		PropertyRow * pRow = GetActiveRowPtr();
		if (pRow->IsExpanded())
			pRow->Collapse();
		else
			pRow->Expand();
		break;
	}
	case VK_LEFT:
		GetActiveRowPtr()->Collapse();
		break;
	case VK_RIGHT:
		GetActiveRowPtr()->Expand();
		break;
	}
}

} // My